#include <iostream>
#include <string>
#include <memory>

// Step 1: 抽象主题 (Subject)
class Image {
public:
    virtual ~Image() = default;

    // 显示图像
    virtual void display() const = 0;
};

// Step 2: 真实主题 (RealSubject)
class RealImage : public Image {
private:
    std::string filename_; // 图像文件名

    // 模拟加载图像
    void loadFromDisk() const {
        std::cout << "Loading image from disk: " << filename_ << std::endl;
    }

public:
    RealImage(const std::string& filename) : filename_(filename) {
        loadFromDisk(); // 加载图像文件
    }

    void display() const override {
        std::cout << "Displaying image: " << filename_ << std::endl;
    }
};

// Step 3: 代理 (Proxy)
class ProxyImage : public Image {
private:
    std::string filename_;               // 图像文件名
    mutable std::shared_ptr<RealImage> realImage_; // 延迟加载的真实图像对象

public:
    ProxyImage(const std::string& filename) : filename_(filename), realImage_(nullptr) {}

    void display() const override {
        if (!realImage_) { // 如果尚未加载真实图像
            realImage_ = std::make_shared<RealImage>(filename_);
        }
        realImage_->display();
    }
};

// Step 4: 客户端代码
int main() {
    std::cout << "Creating proxy for image...\n";
    ProxyImage proxyImage("large_photo.jpg");

    std::cout << "\nImage not loaded yet.\n";

    std::cout << "\nDisplaying image for the first time:\n";
    proxyImage.display(); // 第一次显示图像，加载真实图像

    std::cout << "\nDisplaying image for the second time:\n";
    proxyImage.display(); // 第二次显示图像，不需要再次加载

    return 0;
}
